"""
代理管理器
用于管理IP代理池，自动切换代理
"""
import random
import logging
from typing import List, Optional
from urllib.parse import urlparse
from spider.config.settings import USE_PROXY, PROXY_LIST, PROXY_ROTATION

logger = logging.getLogger(__name__)


class ProxyManager:
    """代理管理器"""
    
    def __init__(
        self,
        proxy_list: Optional[List[str]] = None,
        rotation: bool = PROXY_ROTATION,
        enabled: bool = USE_PROXY,
    ):
        self.proxy_list = proxy_list or PROXY_LIST
        self.rotation = rotation
        self.enabled = enabled and len(self.proxy_list) > 0
        self.current_proxy_index = 0
        self.failed_proxies = set()
    
    def get_proxy(self) -> Optional[dict]:
        """获取当前代理"""
        if not self.enabled:
            return None
        
        if not self.proxy_list:
            logger.warning("Proxy list is empty")
            return None
        
        # 过滤掉失败的代理
        available_proxies = [
            p for p in self.proxy_list
            if p not in self.failed_proxies
        ]
        
        if not available_proxies:
            logger.warning("All proxies have failed, resetting failed list")
            self.failed_proxies.clear()
            available_proxies = self.proxy_list
        
        if self.rotation:
            proxy = random.choice(available_proxies)
        else:
            proxy = available_proxies[self.current_proxy_index % len(available_proxies)]
            self.current_proxy_index += 1
        
        return self._format_proxy(proxy)
    
    def _format_proxy(self, proxy: str) -> dict:
        """格式化代理为requests可用的格式"""
        parsed = urlparse(proxy)
        return {
            'http': proxy,
            'https': proxy,
        }
    
    def mark_failed(self, proxy: str):
        """标记代理为失败"""
        if proxy:
            self.failed_proxies.add(proxy)
            logger.warning(f"Proxy marked as failed: {proxy}")
    
    def reset(self):
        """重置代理管理器"""
        self.current_proxy_index = 0
        self.failed_proxies.clear()

